﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AppHtml
{
    using AppHtml.Control;
    using System.Linq.Expressions;
    using DbFrame.Class;
    using Microsoft.AspNetCore.Html;

    public class UI
    {
        public static Html _Html = new Html();
        private static KOViewModelControl _KOViewModelControl = new KOViewModelControl();

        /// <summary>
        /// 解析表达式
        /// </summary>
        /// <param name="Field"></param>
        /// <returns></returns>
        private static dynamic AnalysisExpression<T>(Expression<Func<T, dynamic>> Field)
            where T : BaseEntity, new()
        {
            var Name = "";
            var Title = "";

            var body = Field.Body;

            MemberExpression member = null;

            if (body is UnaryExpression)
            {
                var _UnaryExpression = body as UnaryExpression;
                member = _UnaryExpression.Operand as MemberExpression;
            }
            else if (body is ConstantExpression)
            {
                //var _ConstantExpression = body as ConstantExpression;

            }
            else if (body is MethodCallExpression)
            {
                //var _ConstantExpression = body as MethodCallExpression;
            }
            else if (body is MemberExpression)
            {
                member = body as MemberExpression;
            }



            if (member == null) throw new Exception("语法错误!");

            Name = member.Member.Name;

            var _FieldAttribute = member.Member.GetCustomAttributes(typeof(FieldAttribute), false).FirstOrDefault() as FieldAttribute;
            if (_FieldAttribute == null) throw new ArgumentNullException("属性 " + Name + " 找不到 自定义特性 ObjectRemarks.FieldAttribute ");

            Title = _FieldAttribute.Alias;

            return new { Name = Name, Title = Title };
        }

        /// <summary>
        /// Input 控件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="Field"></param>
        /// <param name="Placeholder"></param>
        /// <param name="Attribute"></param>
        /// <param name="Col"></param>
        /// <param name="Type"></param>
        /// <returns></returns>
        public static HtmlString Input<T>(Expression<Func<T, dynamic>> Field, string Type = "text", object Attribute = null, int Col = 6, string Placeholder = null)
            where T : BaseEntity, new()
        {
            var Obj = AnalysisExpression(Field);

            return new HtmlString(_Html.Input(Obj.Title, Obj.Name, Placeholder, Attribute, Col, Type));
        }

        /// <summary>
        /// Input 控件 自定义属性 方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="Field"></param>
        /// <param name="Attribute"></param>
        /// <param name="Col"></param>
        /// <returns></returns>
        public static HtmlString InputCustom<T>(Expression<Func<T, object>> Field, object Attribute, int Col = 6)
            where T : BaseEntity, new()
        {
            var Obj = AnalysisExpression(Field);

            return new HtmlString(_Html.Input(Obj.Title, Attribute, Col));
        }

        /// <summary>
        /// Slect 控件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="Field"></param>
        /// <param name="FuncOpetion"></param>
        /// <param name="Col"></param>
        /// <param name="Attribute"></param>
        /// <returns></returns>
        public static HtmlString Select<T>(Expression<Func<T, object>> Field, Func<string> FuncOpetion, int Col = 6, object Attribute = null)
            where T : BaseEntity, new()
        {
            var Obj = AnalysisExpression(Field);

            return new HtmlString(_Html.Select(Obj.Title, Obj.Name, FuncOpetion, Attribute, Col));
        }

        /// <summary>
        /// Slect 控件 自定义属性 方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="Field"></param>
        /// <param name="Attribute"></param>
        /// <param name="FuncOpetion"></param>
        /// <param name="Col"></param>
        /// <returns></returns>
        public static HtmlString SelectCustom<T>(Expression<Func<T, object>> Field, string Attribute, Func<string> FuncOpetion, int Col = 6)
        where T : BaseEntity, new()
        {
            var Obj = AnalysisExpression(Field);

            return new HtmlString(_Html.Select(Obj.Title, Attribute, FuncOpetion, Col));
        }

        /// <summary>
        /// 查找带回 控件
        /// </summary>
        /// <param name="Options"></param>
        /// <param name="Readonly"></param>
        /// <param name="KO"></param>
        /// <returns></returns>
        public static HtmlString FindBack<T, T1>(Expression<Func<T, object>> Text, Expression<Func<T1, object>> ID, string Url, string FindClick, string RemoveClick, int Col = 6, string Placeholder = null, bool Readonly = true, bool KO = true)
            where T : BaseEntity, new()
            where T1 : BaseEntity, new()
        {
            var Obj = AnalysisExpression(Text);
            var Obj1 = AnalysisExpression(ID);

            var _New_Placeholder = (string.IsNullOrEmpty(Placeholder) ? "请选择 " + Obj.Title : Placeholder);

            if (FindClick.Contains("#Placeholder"))
                FindClick = FindClick.Replace("#Placeholder", _New_Placeholder);
            if (FindClick.Contains("#Url"))
                FindClick = FindClick.Replace("#Url", Url);

            var Options = new
            {
                Text = Obj.Name,
                ID = Obj1.Name,
                Placeholder = _New_Placeholder,
                FindClick = FindClick,
                RemoveClick = RemoveClick
            };

            var Html = _Html.FindBack(Options, Readonly, KO);

            var H4 = AppHtml.BaseControl.PageControl.H4(new Dictionary<string, string> {
                {"class","example-title"}
            }, Obj.Title);

            var _Div_Attribute = new Dictionary<string, string>();
            _Div_Attribute.Add("class", "col-sm-" + Col);

            return new HtmlString(AppHtml.BaseControl.PageControl.Div(_Div_Attribute, H4 + Html));
        }

        /// <summary>
        /// 上传图片 控件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="Field"></param>
        /// <param name="Col"></param>
        /// <param name="Width"></param>
        /// <param name="Height"></param>
        /// <returns></returns>
        public static HtmlString UploadImage<T>(Expression<Func<T, object>> Field, int Col = 6, int Width = 150, int Height = 150)
            where T : BaseEntity, new()
        {
            var Obj = AnalysisExpression(Field);

            return new HtmlString(_Html.UploadImage(Obj.Title, Obj.Name, Col, Width, Height));
        }

        /// <summary>
        /// UEditor 编辑器
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="Field"></param>
        /// <param name="Col"></param>
        /// <param name="Width"></param>
        /// <param name="Height"></param>
        /// <returns></returns>
        public static HtmlString UEditor<T>(Expression<Func<T, object>> Field, int Col = 6, string Width = "100%", string Height = "300px")
            where T : BaseEntity, new()
        {

            var Obj = AnalysisExpression(Field);

            return new HtmlString(_Html.UEditor(Obj.Title, Obj.Name, Col, Width, Height));
        }


        /// <summary>
        /// 创建 KO 实体
        /// </summary>
        /// <returns></returns>
        public static HtmlString CreateKOViewModel(DbFrame.Class.BaseEntity Model, string[] More = null)
        {
            return new HtmlString(_KOViewModelControl.ScriptStr(Model, More).ToString());
        }

        /// <summary>
        /// 创建 KO 实体
        /// </summary>
        /// <returns></returns>
        public static HtmlString CreateKOViewModel(List<DbFrame.Class.BaseEntity> Model, string[] More = null)
        {
            return new HtmlString(_KOViewModelControl.ScriptStr(Model, More).ToString());
        }








    }
}
